// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Linq;

namespace SnapObjects.Data
{
    internal class SqlBuilderTokenizer : SqlTokenizerBase
    {
        protected char[] _parameterIdentifiers = { '@', ':' };
        protected string _parseSqlText;

        public SqlBuilderTokenizer(string sqlText) : base(sqlText)
        {

        }

        public string GetSqlString()
        {
            return _parseSqlText;
        }

        public bool ReplaceParameter(ISqlBuilderParameter[] parameters)
        {
            var result = false;

            var tokens = this.GetTokens();

            for (var i = 0; i < tokens.Count; i++)
            {
                var token = tokens[i];

                if (token.Length > 1)
                {
                    var firstChar = token[0];
                    var secondChar = token[1];

                    if (_parameterIdentifiers.Contains(firstChar) && firstChar != secondChar)
                    {
                        var name = token.Substring(1);

                        var param = parameters.FirstOrDefault(
                            m => m.Name.Equals(name, StringComparison.OrdinalIgnoreCase));

                        if (param != null)
                        {
                            tokens[i] = param.ParameterName;

                            result = true;
                        }
                        else
                        {
                            throw new Exception($"Parameter '{name}' is not defined.");
                        }
                    }
                    else
                    {
                        var param = parameters.FirstOrDefault(
                            m => m.PlaceholdName.Equals(token, StringComparison.OrdinalIgnoreCase));

                        if (param != null)
                        {
                            tokens[i] = param.ParameterName;

                            result = true;
                        }
                    }
                }
            }

            _parseSqlText = String.Join("", tokens);

            return result;
        }
    }
}
